
// Copyright (c) WanSheng Intelligent Corp. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#ifndef __WA__SDK__H_
#define __WA__SDK__H_
#include <stdbool.h>
#include <stdint.h>
#include "plugin_constants.h"
#include "wa_sdkver.h"
#ifdef __cplusplus
extern "C" {
#endif


typedef struct _restful_ex
{
    unsigned long  mid;
    uint64_t time;    // RESTFUL_TIME_NO_SET means no time set
}restful_ex_t;

#define RESTFUL_TIME_NO_SET ((uint64_t) -1)


typedef struct _restful_request
{
    rest_action_t action;
    wa_format_type_t payload_fmt;
    int payload_len;
    char * payload;
    char * url;
    char * query;
    restful_ex_t * ex;  // normally is NULL
}restful_request_t;


typedef struct _restful_response
{
    int code;
    wa_format_type_t payload_fmt;
    int payload_len;
    char * payload;
}restful_response_t;


typedef struct REST_CONTEXT_TAG *   RESTFUL_CONTEXT;
typedef struct REQ_ENV_TAG*         REQ_ENV_HANDLE;
typedef struct restful_remote_job * restful_remote_job_t;

typedef void (*RemoteHandler) (void * msg);
typedef void (*WA_Resource_Handler) (restful_request_t *request, REQ_ENV_HANDLE req_env);
typedef void (*WA_Result_Handler) (RESTFUL_CONTEXT context, restful_response_t *response, void * user_data);
typedef void (*WA_Timer_Handler) (RESTFUL_CONTEXT context, void * user_data);
typedef void (*RestfulRemoteHandler) (restful_remote_job_t job, RemoteHandler job_handler, void * arg_for_poster);


char * rest_action_str(int action);

int action_from_string(char* action);

char * rest_fmt_str(wa_format_type_t fmt, char * buffer);

// the payload, url and query will be refered by the request object
void wa_setup_request(restful_request_t *,
        int action,
        wa_format_type_t payload_fmt,
        int payload_len,
        char * payload,
        char * url,
        char * query);

// the request and fields will be allocated and copied by the function
restful_request_t *  wa_new_request(
        int action,
        wa_format_type_t payload_fmt,
        int payload_len,
        char * payload,
        char * url,
        char * query);

void wa_free_request(restful_request_t * request);


void wa_setup_response(restful_response_t * response,
        int status,
        wa_format_type_t payload_fmt,
        int payload_len, void *payload);

// payload_to_clone: will be allocated internaly and copied.
restful_response_t * wa_new_response(int status, wa_format_type_t fmt, int payload_len, const char* payload_to_clone);

// The response and its owning buffer will be cloned
restful_response_t* wa_clone_response(restful_response_t * response);

// The payload will be handed over to the new allocated response. Its value is set to NULL in the function
restful_response_t* wa_new_response_handover_payload(int status, wa_format_type_t format, int payload_len, char ** payload_handover);

// The response and its owning payload will be freed.
void wa_free_response(restful_response_t * response);



RESTFUL_CONTEXT wa_req_env_get_context(REQ_ENV_HANDLE req_env);

REQ_ENV_HANDLE wa_req_env_clone(REQ_ENV_HANDLE req_env);

void wa_req_env_destroy(REQ_ENV_HANDLE req_env);

bool wa_req_env_want_response(REQ_ENV_HANDLE req_env);

// Send out the response that was set into the req_env.
// The user request handler doesn't need to call this, 
// as the framework will send out the response.
// If no reponse was set, then framework won't send out response.
// So the caller can clone the req_env and send the response later.
void wa_send_response(REQ_ENV_HANDLE req_env);

// Set the response to the request environment. The framework will 
// send out the response after the user handler returned.
// Payload: it will be cloned internally.
void wa_set_response(REQ_ENV_HANDLE env, int status, wa_format_type_t fmt, int payload_len, const char* payload);

// Setup the response in the req-env, and the payload buffer is transfered to the framework.
// After the function return, the value of payload pointer will be set to NULL.
void wa_req_env_handover_payload(REQ_ENV_HANDLE env, int status, wa_format_type_t fmt, int payload_len, const char** payload);

// Transfer the response to the req-env.
// resp: caller must allocate it before calling and no longer use it after calling. 
//       later the framework will free the response after sending it out.
void wa_req_env_handover_response(REQ_ENV_HANDLE env, restful_response_t ** resp); 

void wa_set_response_status(REQ_ENV_HANDLE env, int status);

/*
    @brief  set the resource type for registered resource.
            The information can be used for generating the Resource Directory message.
*/
bool wa_resource_set_type(RESTFUL_CONTEXT context, const char * url, const char * resource_type);


#ifdef __cplusplus
}
#endif


#endif /* __WA_PLUGIN_SDK__H_ */
